package org.yasukusury.crawler.helper;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor;
import org.yasukusury.crawler.variation.AbstractBatches;

import java.io.*;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URLEncoder;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Y
 * Date: 2017-11-15
 * Time: 13:57
 */
public class Utils {
    public static final String[] month = new String[]{"January", "February", "March", "April", "May", "June"
            , "July", "Aguest", "September", "October", "November", "December"};
    public static final String[] dateFormat = new String[]{"yyyy-MM-dd"};
    public static final int timeout = 6000;
    public static String[] param = new String[]{"ie", "UTF8", "reviewerType", "all_reviews", "formatType", "current_format", "pageNumber"};
    //    ?ie=UTF8&reviewerType=all_reviews&formatType=current_format&pageNumber=1
    public static int retryCount = 3;

    public static Document httpClientGet(URI uri, String asin, int pages) throws IOException {
        String[] html = new String[]{"", ""};
        Document doc = null;
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(timeout)
                .setConnectTimeout(timeout)
                .setConnectionRequestTimeout(timeout)
                .build();
        CloseableHttpClient client = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();
        HttpGet httpGet = new HttpGet(uri);
        int count = 0;
        while (count < retryCount) {
            try {
                CloseableHttpResponse response = client.execute(httpGet);
                html[0] = String.valueOf(response.getStatusLine().getStatusCode());
                html[1] = EntityUtils.toString(response.getEntity(), "utf-8");
                response.close();
            } catch (SocketTimeoutException | ConnectTimeoutException e) {
                count++;
                System.out.println(String.format("ASIN : %s 评论第 %d 页超时第%d次", asin, pages, count));
            }
            if ("200".equals(html[0])) {
                doc = Jsoup.parse(html[1]);
                break;
            }
        }
        client.close();
        return doc;
    }

    public static String getUTF8XMLString(String xml) {
        // A StringBuffer Object
        String xmString = "";
        String xmlUTF8 = "";
        try {
            xmString = new String(xml.getBytes("UTF-8"));
            xmlUTF8 = URLEncoder.encode(xmString, "UTF-8");
//            System.out.println(xmlUTF8) ;
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // return to String Formed
        return xmlUTF8;
    }

    public static String txt2String(File file) {
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
            String s = null;
            while ((s = br.readLine()) != null) {//使用readLine方法，一次读一行
                result.append(System.lineSeparator()).append(s);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    public static String getPlainText(Element element) {
        if (element == null)
            return null;
        FormattingVisitor formatter = new FormattingVisitor();
        NodeTraversor traversor = new NodeTraversor(formatter);
        traversor.traverse(element);
        return formatter.toString();
    }

    private static class FormattingVisitor implements NodeVisitor {
        private static final int maxWidth = 80;
        private int width = 0;
        private StringBuilder accum = new StringBuilder(); // holds the accumulated text

        // hit when the node is first seen
        public void head(Node node, int depth) {
            String name = node.nodeName();
            if (node instanceof TextNode)
                append(((TextNode) node).text()); // TextNodes carry all user-readable text in the DOM.
            else if (name.equals("li"))
                append("\n * ");
            else if (name.equals("dt"))
                append("  ");
            else if (StringUtil.in(name, "p", "h1", "h2", "h3", "h4", "h5", "tr"))
                append("\n");
        }

        // hit when all of the node's children (if any) have been visited
        public void tail(Node node, int depth) {
            String name = node.nodeName();
            if (StringUtil.in(name, "br", "dd", "dt", "p", "h1", "h2", "h3", "h4", "h5"))
                append("\n");
//            else if (name.equals("a"))
//                append(String.format(" <%s>", node.absUrl("href")));
        }

        // appends text to the string builder with a simple word wrap method
        private void append(String text) {
            if (text.startsWith("\n"))
                width = 0; // reset counter if starts with a newline. only from formats above, not in natural text
            if (text.equals(" ") &&
                    (accum.length() == 0 || StringUtil.in(accum.substring(accum.length() - 1), " ", "\n")))
                return; // don't accumulate long runs of empty spaces

//            if (text.length() + width > maxWidth) { // won't fit, needs to wrap
//                String words[] = text.split("\\s+");
//                for (int i = 0; i < words.length; i++) {
//                    String word = words[i];
//                    boolean last = i == words.length - 1;
//                    if (!last) // insert a space if not the last word
//                        word = word + " ";
//                    if (word.length() + width > maxWidth) { // wrap and reset counter
//                        accum.append("\n").append(word);
//                        width = word.length();
//                    } else {
//                        accum.append(word);
//                        width += word.length();
//                    }
//                }
//            } else { // fits as is, without need to wrap text
            accum.append(text);
            width += text.length();
//            }
        }

        @Override
        public String toString() {
            return accum.toString();
        }
    }
}
